package com.gill.demo;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;

/**
 * curator利用NodeCache实现注册1次watcher监听多次的demo演示
 */
public class CuratorZnodeWatcherMore {

    public CuratorFramework client;
    public static final String zkServerPath = "env:2181";

    /**
     * 实例化zk客户端
     */
    public CuratorZnodeWatcherMore() {
        /**
         * curator连接zookeeper的策略:RetryNTimes（本次案例采用该连接策略）
         * n：重试的次数
         * sleepMsBetweenRetries：每次重试间隔的时间
         */
        RetryPolicy retryPolicy = new RetryNTimes(3, 5000);

        client = CuratorFrameworkFactory.builder()
                .connectString(zkServerPath)
                .sessionTimeoutMs(10000)
                .retryPolicy(retryPolicy)
                .namespace("workspace")
                .build();

        // 连接zk服务端
        client.start();

    }

    /**
     *
     * @Description: 关闭zk客户端连接
     */
    public void closeZKClient() {
        if (client != null) {
            this.client.close();
        }
    }

    public static void main(String[] args) throws Exception {
        // 连接zk服务端，创建zk客户端实例
        CuratorZnodeWatcherMore curator = new CuratorZnodeWatcherMore();
        boolean isZkCuratorStarted = curator.client.isStarted();
        System.out.println("当前客户的状态：" + (isZkCuratorStarted ? "连接中" : "已关闭"));

        // 注册1次，监听多次（使用NodeCache实现，可以监听节点的增删改）
        String nodePath = "/super/imooc";
        final NodeCache nodeCache = new NodeCache(curator.client, nodePath);//监听数据节点的变更，会触发事件
		nodeCache.start(true);//初始化的时候获取node的值并且缓存
		if (nodeCache.getCurrentData() != null) {
			System.out.println("节点初始化数据为：" + new String(nodeCache.getCurrentData().getData()));
		} else {
			System.out.println("节点初始化数据为空...");
		}
		nodeCache.getListenable().addListener(new NodeCacheListener() {
		    @Override
			public void nodeChanged() throws Exception {
				if (nodeCache.getCurrentData() == null) {
					System.out.println("节点为空");
					return;
				}
				String data = new String(nodeCache.getCurrentData().getData());
				System.out.println("节点路径：" + nodeCache.getCurrentData().getPath() + "数据：" + data);
			}
		});

        // 阻塞main线程，到zk服务端修改节点值，查看是否触发
        System.in.read();
    }

    private static class MyCuratorWatcher implements CuratorWatcher {
        @Override
        public void process(WatchedEvent watchedEvent) throws Exception {
            System.out.println("触发watcher，节点路径为：" + watchedEvent.getPath());
        }
    }

    private static class MyWatcher implements Watcher {
        @Override
        public void process(WatchedEvent event) {
            System.out.println("触发watcher，节点路径为：" + event.getPath());
        }
    }
}
